package com.itzb.asone.redis;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import com.alibaba.fastjson.JSON;

public class RedisPool
{

	private static final Logger logger = LoggerFactory.getLogger(RedisPool.class);

	private static Map<String, JedisPool> mapPool = new HashMap<String, JedisPool>();

	private static String SERVICE_NAME;
	// linux 服务器的url --- redis
	private static String SERVICE_URL;
	private static String REDIS_PORT;
	// 设置最大的连接数
	private static String MAX_TOTAL;
	// 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
	private static String MAX_IDLE;
	// 表示当borrow(引入)一个jedis实例时，最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException；
	private static String MAX_WAIT_MILLIS;
	// 在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
	private static String TEST_ON_BORROW;
	// 在还会给pool时，是否提前进行validate操作
	private static String TEST_ON_RETURN;

	// 静态代码初始化池配置
	public static void init()
	{

		logger.info("************************************************");
		logger.info("***** Load redis pool configuration start. *****");

		String[] SERVICE_NAMES = SERVICE_NAME.split(",");
		String[] SERVICE_URLS = SERVICE_URL.split(",");
		String[] REDIS_PORTS = REDIS_PORT.split(",");
		String[] MAX_IDLES = MAX_IDLE.split(",");
		String[] MAX_TOTALS = MAX_TOTAL.split(",");
		String[] MAX_WAIT_MILLISS = MAX_WAIT_MILLIS.split(",");
		String[] TEST_ON_BORROWS = TEST_ON_BORROW.split(",");
		String[] TEST_ON_RETURNS = TEST_ON_RETURN.split(",");

		for (int i = 0; i < SERVICE_NAMES.length; i++)
		{

			logger.info("***** Load redis  " + (i + 1) + "/" + SERVICE_NAMES.length + "  *****");
			logger.info("***** " + SERVICE_NAMES[i] + " maxIdle:" + MAX_IDLES[i] + " maxTotal:" + MAX_TOTALS[i] + " maxWaitMillis:" + MAX_WAIT_MILLISS[i] + " testOnBorrow:" + TEST_ON_BORROWS[i] + " testOnReturn:" + TEST_ON_RETURNS[i]);

			// 创建jedis池配置实例
			JedisPoolConfig config = new JedisPoolConfig();

			// 设置池配置项值
			// 控制一个pool最多有多少个状态为idle(空闲的)的jedis实例。
			config.setMaxIdle(Integer.parseInt(MAX_IDLES[i]));

			// 设置最大连接数
			config.setMaxTotal(Integer.parseInt(MAX_TOTALS[i]));

			// 表示当borrow(引入)一个jedis实例时，最大的等待时间，如果超过等待时间，则直接抛出JedisConnectionException；
			config.setMaxWaitMillis(Integer.parseInt(MAX_WAIT_MILLISS[i]));

			// 在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
			config.setTestOnBorrow(Boolean.getBoolean(TEST_ON_BORROWS[i]));

			// 在还会给pool时，是否提前进行validate操作
			config.setTestOnReturn(Boolean.getBoolean(TEST_ON_RETURNS[i]));

			// 根据配置实例化jedis池
			JedisPool pool = new JedisPool(config, SERVICE_URLS[i], Integer.parseInt(REDIS_PORTS[i]));

			// 根据 SERVICE_NAME 把连接池存放到 mapPool 中
			mapPool.put(SERVICE_NAMES[i], pool);
		}

		logger.info("***** Load redis pool configuration end.   *****");

	}

	/** 获得jedis对象 */
	public static Jedis getJedisObject(String serverName)
	{
		return mapPool.get(serverName).getResource();
	}

	/** 归还jedis对象 */
	public static void recycleJedisOjbect(String serverName, Jedis jedis)
	{
		try
		{
			mapPool.get(serverName).returnResource(jedis);
		}
		catch (Exception e)
		{
			logger.error("redis is setJedis val Error! method[setJedis(String serverName=" + serverName + ", String jedis=" + jedis + ")]");
		}
	}

	public void setJedis(String serverName, String key, String value)
	{
		Jedis jedis = getJedisObject(serverName);// 获得jedis实例
		try
		{
			jedis.set(key, value);
		}
		catch (Exception e)
		{
			logger.error("redis is setJedis val Error! method[setJedis(String serverName=" + serverName + ", String key=" + key + ", String value=" + value + ")]");
		}
		finally
		{
			recycleJedisOjbect(serverName, jedis); // 将 获取的jedis实例对象还回迟中
		}
	}

	public void setJedisList(String serverName, String key, List<String> value)
	{
		Jedis jedis = getJedisObject(serverName);// 获得jedis实例
		try
		{
			for (String val : value)
			{
				jedis.lpush(key, val);
			}
		}
		catch (Exception e)
		{
			logger.error("redis is setJedisList val Error! method[setJedisList(String serverName=" + serverName + ", String key=" + key + ", List<String> value=" + value.toString() + ")]");
		}
		finally
		{
			recycleJedisOjbect(serverName, jedis); // 将 获取的jedis实例对象还回迟中
		}
	}

	public void setJedisMap(String serverName, String key, Map<String, String> map)
	{
		Jedis jedis = getJedisObject(serverName);// 获得jedis实例;
		try
		{
			jedis.hmset(key, map);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			logger.error("redis is setJedisList val Error! method[setJedisMap(String serverName=" + serverName + ", String key=" + key + ", Map<String, String> map=" + map.toString() + ")]");
		}
		finally
		{
			recycleJedisOjbect(serverName, jedis); // 将 获取的jedis实例对象还回迟中
		}
	}

	public void setJedisObject(String serverName, String key, Object obj)
	{
		Jedis jedis = getJedisObject(serverName);// 获得jedis实例
		try
		{
			String objectJson = JSON.toJSONString(obj);
			jedis.set(key, objectJson);
			recycleJedisOjbect(serverName, jedis); // 将 获取的jedis实例对象还回迟中
		}
		catch (Exception ex)
		{
			ex.printStackTrace();
		}
	}

	public String getJedis(String serverName, String key)
	{
		String val = "";
		Jedis jedis = getJedisObject(serverName);// 获得jedis实例
		try
		{
			val = jedis.get(key);
		}
		catch (Exception e)
		{
			logger.error("redis is getJedis val Error! method[getJedis(String serverName=" + serverName + ", String key=" + key + ")]");
		}
		finally
		{
			recycleJedisOjbect(serverName, jedis); // 将 获取的jedis实例对象还回迟中
		}
		return val;
	}

	/**
	 * 获取redis中存放的
	 * 
	 * @param mapName
	 * @return
	 */
	public Map<String, String> getJedisMap(String serverName, String mapName)
	{
		Jedis jedis = getJedisObject(serverName);// 获得jedis实例
		Set<String> listMapKey = jedis.hkeys(mapName);
		Map<String, String> map = new HashMap<String, String>();
		for (String key : listMapKey)
		{
			List<String> value = jedis.hmget(mapName, key);
			map.put(key, value.get(0));
		}
		recycleJedisOjbect(serverName, jedis); // 将 获取的jedis实例对象还回迟中
		return map;
	}

	public List<String> getJedisList(String serverName, String key)
	{
		Jedis jedis = getJedisObject(serverName);// 获得jedis实例
		List<String> list = jedis.lrange(key, 0, -1);
		recycleJedisOjbect(serverName, jedis); // 将 获取的jedis实例对象还回迟中
		return list;
	}

	public void delJedis(String serverName, String key)
	{
		Jedis jedis = getJedisObject(serverName);// 获得jedis实例
		jedis.del(key);
		recycleJedisOjbect(serverName, jedis); // 将 获取的jedis实例对象还回迟中
	}

	/**
	 * 删除所有数据库中的所有key，此方法不会失败。更加慎用
	 * 
	 * @param key
	 * @param value
	 */
	public void delDB(String serverName)
	{
		Jedis jedis = getJedisObject(serverName);// 获得jedis实例
		jedis.flushDB();// 删除所有数据库中的所有key，此方法不会失败。更加慎用
	}

	/**
	 * 删除所有数据库中的所有key，此方法不会失败。更加慎用
	 * 
	 * @param key
	 * @param value
	 */
	public void delALL(String serverName)
	{
		Jedis jedis = getJedisObject(serverName);// 获得jedis实例
		jedis.flushAll();// 删除所有数据库中的所有key，此方法不会失败。更加慎用
	}
	
	public Long getSeq(String serverName,String seqName){
		Jedis jedis = getJedisObject(serverName);// 获得jedis实例
		Long seq=null;
		try
		{
			seq = jedis.incr(seqName);
			if(seq>999999){
				jedis.set(seqName, "0");
			}
		}catch(Exception e){
			logger.error("redis is incr val Error!seqName:"+seqName);
		}finally{
			recycleJedisOjbect(serverName, jedis); 
		}
		return seq;
	}

	/**
	 * 
	 * 测试jedis池方法
	 */

	public static void main(String[] args)
	{

		String serverName = "";

		Jedis jedis = getJedisObject(serverName);// 获得jedis实例

	}

	/**
	 * set方法
	 * 
	 * @param uRL
	 */
	public static Map<String, JedisPool> getMapPool()
	{
		return mapPool;
	}

	public static void setMapPool(Map<String, JedisPool> mapPool)
	{
		RedisPool.mapPool = mapPool;
	}

	public static String getSERVICE_NAME()
	{
		return SERVICE_NAME;
	}

	public static void setSERVICE_NAME(String sERVICE_NAME)
	{
		SERVICE_NAME = sERVICE_NAME;
	}

	public static String getSERVICE_URL()
	{
		return SERVICE_URL;
	}

	public static void setSERVICE_URL(String sERVICE_URL)
	{
		SERVICE_URL = sERVICE_URL;
	}

	public static String getREDIS_PORT()
	{
		return REDIS_PORT;
	}

	public static void setREDIS_PORT(String rEDIS_PORT)
	{
		REDIS_PORT = rEDIS_PORT;
	}

	public static String getMAX_IDLE()
	{
		return MAX_IDLE;
	}

	public static void setMAX_IDLE(String mAX_IDLE)
	{
		MAX_IDLE = mAX_IDLE;
	}

	public static String getMAX_WAIT_MILLIS()
	{
		return MAX_WAIT_MILLIS;
	}

	public static void setMAX_WAIT_MILLIS(String mAX_WAIT_MILLIS)
	{
		MAX_WAIT_MILLIS = mAX_WAIT_MILLIS;
	}

	public static String getTEST_ON_BORROW()
	{
		return TEST_ON_BORROW;
	}

	public static void setTEST_ON_BORROW(String tEST_ON_BORROW)
	{
		TEST_ON_BORROW = tEST_ON_BORROW;
	}

	public static String getTEST_ON_RETURN()
	{
		return TEST_ON_RETURN;
	}

	public static void setTEST_ON_RETURN(String tEST_ON_RETURN)
	{
		TEST_ON_RETURN = tEST_ON_RETURN;
	}

	public static String getMAX_TOTAL()
	{
		return MAX_TOTAL;
	}

	public static void setMAX_TOTAL(String mAX_TOTAL)
	{
		MAX_TOTAL = mAX_TOTAL;
	}

}
